package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.client.CourseFeignClient;
import cn.itsource.ymcc.constants.BaseConstants;
import cn.itsource.ymcc.context.LoginContext;
import cn.itsource.ymcc.domain.Course;
import cn.itsource.ymcc.domain.CourseCart;
import cn.itsource.ymcc.domain.CourseMarket;
import cn.itsource.ymcc.domain.Login;
import cn.itsource.ymcc.dto.CourseInfoDto;
import cn.itsource.ymcc.exception.GlobleException;
import cn.itsource.ymcc.mapper.CourseCartMapper;
import cn.itsource.ymcc.result.JSONResult;
import cn.itsource.ymcc.service.ICourseCartService;
import cn.itsource.ymcc.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author whale
 * @since 2021-10-31
 */
@Service
@Slf4j
public class CourseCartServiceImpl extends ServiceImpl<CourseCartMapper, CourseCart> implements ICourseCartService {

    @Autowired
    private CourseFeignClient courseFeignClient;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Value("${cart.limit}")
    private int cartLimit = 20;

    @Override
    public void add(Long courseId) {
        Long userId = LoginContext.getLogin().getId();

        //购物车已经存在
        BoundHashOperations<Object, Object, CourseCart> boundHashOperations = redisTemplate.boundHashOps(BaseConstants.Cart.KEY_USERS_CART_2REDIS+":"+userId);
        if(boundHashOperations.hasKey(courseId.toString())){
            throw new GlobleException("课程已经被加入购物车");
        }

        //购物车数量
        if(boundHashOperations.keys().size() > cartLimit){
            throw new GlobleException("购物车最多只能添加 "+cartLimit+" 个");
        }


        //查询课程
        JSONResult jsonResult = courseFeignClient.getCourseInfo(courseId);
        AssertUtil.isNotNull(jsonResult,"课程数据获取失败");
        AssertUtil.isNotNull(jsonResult.getData(),"课程数据获取失败");
        CourseInfoDto courseInfoDto = JSON.parseObject(jsonResult.getData().toString(), CourseInfoDto.class);

        //课程数据
        Course course = courseInfoDto.getCourse();
        CourseMarket courseMarket = courseInfoDto.getCourseMarket();

        //保存购物车数据
        CourseCart courseCart = new CourseCart();
        courseCart.setCount(1);
        courseCart.setCourseId(courseId);
        courseCart.setCourseName(course.getName());
        courseCart.setCourseNote("等级："+course.getGradeName()+" ; 适合："+course.getForUser());
        courseCart.setCoursePic(course.getPic());
        courseCart.setCoursePrice(courseMarket.getPrice());
        courseCart.setLoginId(userId);
        courseCart.setCreateTime(new Date());
        courseCart.setStatus(BaseConstants.Cart.STATUS_NORMAL);
        courseCart.setGradeName(course.getGradeName());
        courseCart.setOldCoursePrice(courseMarket.getPriceOld());
        //insert(courseCart);

        boundHashOperations.put(courseId.toString() ,courseCart );

        //boundHashOperations.expire(30 , TimeUnit.DAYS);
        log.info("添加用户的购物车到Redis...{}",courseCart);
    }

    @Override
    public List<CourseCart> listForUser() {
        Long userId = LoginContext.getLogin().getId();
        BoundHashOperations<Object, Object, CourseCart> boundHashOperations = redisTemplate.boundHashOps(BaseConstants.Cart.KEY_USERS_CART_2REDIS+":"+userId);
        if(!boundHashOperations.keys().isEmpty()){
            log.info("从Redis加载用户的购物车");
            return boundHashOperations.values();
        }

        log.info("购物车为空...");
        return new ArrayList<>();
    }


    @Override
    public BigDecimal calAmount(List<Long> courseIds) {

        //总价
        BigDecimal totalAmount = new BigDecimal("0.00");

        //过滤出选中的购物车
        List<CourseCart> courseCarts = new ArrayList<>(courseIds.size());

        //加载用户的购物车
        for(CourseCart courseCart:listForUser()) {
            if(courseIds.contains(courseCart.getCourseId())){
                totalAmount = totalAmount.add(courseCart.getCoursePrice());
            }
        }
        log.info("计算价格{} - {} ",courseIds,totalAmount);
        return totalAmount;
    }

    @Override
    public void remove(List<Long> courseIds) {
        Long userId = LoginContext.getLogin().getId();
        BoundHashOperations<Object, Object, Object> boundHashOperations = redisTemplate.boundHashOps(BaseConstants.Cart.KEY_USERS_CART_2REDIS+":"+userId);

        List<String> ids = courseIds.stream().map(id -> id.toString()).collect(Collectors.toList());
        boundHashOperations.delete(ids.toArray());
        log.info("删除用户购物");
    }
}
